package com.wnxy.portal.service.impl;
import com.google.common.collect.Lists;
import java.math.BigDecimal;
import java.util.*;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.wnxy.portal.common.constant.RedisConstant;
import com.wnxy.portal.entity.Book;
import com.wnxy.portal.mapper.BookMapper;
import com.wnxy.portal.model.vo.CartItemVo;
import com.wnxy.portal.model.vo.CartVo;
import com.wnxy.portal.service.ICartService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

@Service
public class CartServiceImpl implements ICartService {

    @Autowired
    private BookMapper bookMapper;
    @Autowired
    private RedisTemplate redisTemplate;

    // hash类型： user:cart:1 100 CartItemVo
    @Override
    public void addCart(String userId, Long bookId) {

        //1. 先从Redis中获取购物项
        String key = RedisConstant.USER_CART_PREFIX + userId;
        String json = (String) redisTemplate.opsForHash().get(key,bookId.toString());
        //2. 判断：
        CartItemVo cartItemVo = null;
        if (StringUtils.isEmpty(json)) {
            //2.1 如果没有获取到，说明没有购买过当前图书，添加到购物车
            Book book = bookMapper.selectById(bookId);
            cartItemVo = BeanUtil.copyProperties(book, CartItemVo.class);
            cartItemVo.setBuyCount(1);
            cartItemVo.setSumPrice(book.getPrice());
        }
        else {
            //2.2 如果当前用户已经购买过当前图书，修改数量、小计
            cartItemVo = JSONUtil.toBean(json, CartItemVo.class);
            // 修改数量+1
            cartItemVo.setBuyCount(cartItemVo.getBuyCount() + 1);
            // 修改小计 = 单价 * 数量
            cartItemVo.setSumPrice(cartItemVo.getPrice().multiply(new BigDecimal(cartItemVo.getBuyCount())));
        }
        // 存到Redis
        redisTemplate.opsForHash().put(key, bookId.toString(), JSONUtil.toJsonStr(cartItemVo));
    }

    @Override
    public CartVo queryCart(String userId) {
        // 根据key获取hash的value, hash的value是map集合
        Map<String,String> entries =
                redisTemplate.opsForHash().entries(RedisConstant.USER_CART_PREFIX + userId);

        // 遍历map集合
        List<CartItemVo> cartItemVos = new ArrayList<>();
        BigDecimal totalPrice = new BigDecimal("0");
        for (Map.Entry<String, String> entry : entries.entrySet()) {
            // entry.getKey()  是bookId
            // entry.getValue() 是CartItemVo
            CartItemVo cartItemVo = JSONUtil.toBean(entry.getValue(),CartItemVo.class);
            cartItemVos.add(cartItemVo);
            totalPrice = totalPrice.add(cartItemVo.getSumPrice());
        }

        // 封装返回结果
        CartVo cartVo = new CartVo();
        cartVo.setCartItemVos(cartItemVos);
        cartVo.setTotalPrice(totalPrice);
        cartVo.setUserId(Long.parseLong(userId));

        return cartVo;
    }

    @Override
    public void changeBuyNum(String userId, Integer bookId, Integer buyCount) {
        String key = RedisConstant.USER_CART_PREFIX + userId;
        String cartItemVoStr = (String) redisTemplate.opsForHash().get(key, bookId.toString());
        // json转换为对象
        CartItemVo cartItemVo = JSONUtil.toBean(cartItemVoStr, CartItemVo.class);
        cartItemVo.setBuyCount(buyCount);
        cartItemVo.setSumPrice(cartItemVo.getPrice().multiply(new BigDecimal(buyCount)));
        // 将修改后的购物项存储到redis中
        redisTemplate.opsForHash().put(key,bookId.toString(),JSONUtil.toJsonStr(cartItemVo));
    }

    @Override
    public void deleteById(String userId, Integer bookId) {
        String key = RedisConstant.USER_CART_PREFIX + userId;
        redisTemplate.opsForHash().delete(key,bookId.toString());
    }

    @Override
    public CartVo queryCalc(String userId, Long... ids) {
        // 购买的商品在redis如何存储？ user:cart:1   bookId   book的json字符串
        List<CartItemVo> cartItemVos = new ArrayList<>();
        BigDecimal totalPrice = new BigDecimal("0");
        if (ids != null && ids.length > 0) {
            for (Long bookId : ids) {
                String key = RedisConstant.USER_CART_PREFIX + userId;
                // 查redis
                String str = (String) redisTemplate.opsForHash().get(key,bookId.toString());
                // 转换
                CartItemVo cartItemVo = JSONUtil.toBean(str, CartItemVo.class);
                cartItemVos.add(cartItemVo);
                // 累计金额
                totalPrice = totalPrice.add(cartItemVo.getSumPrice());
            }
        }
        CartVo cartVo = new CartVo();
        cartVo.setCartItemVos(cartItemVos);
        cartVo.setTotalPrice(totalPrice);
        cartVo.setUserId(Long.parseLong(userId));
        return cartVo;
    }
}
